<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8" />
    <title>Document</title>
    <style>
      :root {
        --w: min(200px, 100%);
        --s: 10px;
        background: #555;
      }

      * {
        margin: 0;
      }

      .grid--masonry {
        display: grid;
        grid-template-columns: repeat(auto-fit, var(--w));
        gap: var(--s);
        padding: var(--s);
      }

      .grid--masonry > * {
        width: var(--w);
        border-radius: 4px;
        box-shadow: 2px 2px 5px rgba(0, 0, 0, 0.7);
        filter: sepia(1);
      }
    </style>
  </head>
  <body>
    <section class="grid--masonry">
      <img
        src="https://images.unsplash.com/photo-1510137600163-2729bc6959a6?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=900&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ"
        alt="black cat"
      />
      <img
        src="https://images.unsplash.com/photo-1587041403375-ddce288f4c49?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ"
        alt="black cat"
      />
      <img
        src="https://images.unsplash.com/photo-1580697895575-883f7c755346?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ"
        alt=""
      />
      <img
        src="https://images.unsplash.com/photo-1581200459935-685903de7d62?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ"
        alt="black cat"
      />
      <img
        src="https://images.unsplash.com/photo-1578264050450-ccc2f77796a1?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ"
        alt="black cat"
      />
      <img
        src="https://images.unsplash.com/photo-1557153921-10129d0f5b6c?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ"
        alt="black cat"
      />
      <img
        src="https://images.unsplash.com/photo-1584049086295-9f2af90efbb4?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ"
        alt="black cat"
      />
      <img
        src="https://images.unsplash.com/photo-1572196663741-b91b8f045330?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ"
        alt="black cat"
      />
      <img
        src="https://images.unsplash.com/photo-1558288215-664da65499af?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ"
        alt="black cat"
      />
      <img
        src="https://images.unsplash.com/photo-1592296109897-9c4d8e490e7a?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ"
        alt="black cat"
      />
      <img
        src="https://images.unsplash.com/photo-1525104885119-8806dd94ad58?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ"
        alt="black cat"
      />
      <img
        src="https://images.unsplash.com/photo-1576532116216-84f6a0aedaf6?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ"
        alt="black cat"
      />
      <img
        src="https://images.unsplash.com/photo-1533629947587-7b04aaa0e837?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ"
        alt="black cat"
      />
      <img
        src="https://images.unsplash.com/photo-1568386895623-74df8a7406f0?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ"
        alt="black cat"
      />
      <img
        src="https://images.unsplash.com/photo-1573777058681-73b866833d90?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ"
        alt="black cat"
      />
      <img
        src="https://images.unsplash.com/photo-1552566852-06d10a5050f4?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ"
        alt="black cat"
      />
      <img
        src="https://images.unsplash.com/photo-1576759470820-77a440a4d45b?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ"
        alt="black cat"
      />
      <img
        src="https://images.unsplash.com/photo-1586891622678-999a4419da34?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ"
        alt="black cat"
      />
      <img
        src="https://images.unsplash.com/photo-1584797318381-5958ca2e6b39?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ"
        alt="black cat"
      />
      <img
        src="https://images.unsplash.com/photo-1529093589387-b486dcc37c15?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ"
        alt="black cat"
      />
      <img
        src="https://images.unsplash.com/photo-1587421803669-b403d010dd80?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ"
        alt="black cat"
      />
      <img
        src="https://images.unsplash.com/photo-1570458436416-b8fcccfe883f?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ"
        alt="black cat"
      />
      <img
        src="https://images.unsplash.com/photo-1518206245806-5c1f4d0c5a2a?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=400&fit=max&ixid=eyJhcHBfaWQiOjE0NTg5fQ"
        alt="black cat"
      />
    </section>

    <script>
      const grid = document.querySelector(".grid--masonry");
      const gap = parseFloat(getComputedStyle(grid).gridRowGap);
      const items = [...grid.children];
      let ncol = 0;
      const minIndex = (arr) => {
        let index = 0;
        let min = arr[0];
        for (let i = 1; i < arr.length; i++) {
          if (min > arr[i]) {
            index = i;
            min = arr[i];
          }
        }
        return index;
      };

      const layout = () => {
        // 获取当前的列数
        let newNcol =
          getComputedStyle(grid).gridTemplateColumns.split(" ").length;
        if (ncol !== newNcol) {
          // 更新新的列数
          ncol = newNcol;
          // 列高度
          const colHeight = new Array(newNcol).fill(0);
          // 删除所有子项上方的margin
          items.forEach((item) => item.style.removeProperty("transform"));

          // 如果仅有一列就已经成功堆砌，不需要处理了，否则
          if (ncol > 1) {
            const tes = new Map();
            // 跳过第一行所有子项，其他子项需要添加 margin-top
            items.slice(ncol).forEach((item, i) => {
              // item 上一行的元素 items[i]
              // item 当前元素则是 items[ncol + i]
              const bottom = items[i].getBoundingClientRect().bottom;
              colHeight[i % ncol] += bottom;
              const top = item.getBoundingClientRect().top;
              item.style.gridColumn = minIndex(colHeight);
              // item.style.transform = `translateY(${bottom + gap - top}px)`;
            });
          }
        }
      };

      console.log("grid", grid, "gap", gap, "items", items, "ncol", ncol);

      window.addEventListener("load", () => {
        layout();
        window.addEventListener("resize", layout);
        // let timer;
        // window.addEventListener("resize", () => {
        //   timer && clearTimeout(timer);
        //   timer = setTimeout(layout, 50);
        // });
      });
    </script>
  </body>
</html>
